#ifndef LINK_LIST_ZHU
#define LINK_LIST_ZHU

#include <cassert>
struct Link
{
    Link(Link* next):next_(next){}
private:
    friend class LinkList;
    friend class Cursor;
    template <typename T> friend class TLinkList;
    Link* next_;
};
struct Cursor
{
    Cursor& operator++(){
        p_ = p_->next_;
        return *this;
    }
    Cursor operator++(int){
        Cursor old(*this);
        p_ = p_->next_;
        return old;
    }
private:
    friend class LinkList;
    template <typename T> friend class TLinkList;    
    friend bool operator==(const Cursor& lhs, const Cursor& rhs);
    friend bool operator!=(const Cursor& lhs, const Cursor& rhs);
    Cursor(Link* p):p_(p){}
    Link *p_;
};
bool operator==(const Cursor& lhs, const Cursor& rhs)
{
    return lhs.p_ == rhs.p_;
}
bool operator!=(const Cursor& lhs, const Cursor& rhs)
{
    return lhs.p_ != rhs.p_;
}
struct LinkList
{
    LinkList():head_(&head_){}
    ~LinkList(){assert(is_empty());}
    Link& operator[](Cursor const& p){
            return *p.p_->next_;
    }
    Link const& operator[](const Cursor& p)const{
            return *p.p_->next_;
    }
    void insert(Cursor p, Link* link){
            assert(p.p_->next_ && link && (link->next_ == 0));
            link->next_ = p.p_->next_;
            p.p_->next_ = link;
    }
    Link* extractor(Cursor p){
        Link* link = p.p_->next_;
        assert(link and link != head_.next_);
        p.p_->next_ = link->next_;
        link->next_ = 0;
        return link;
    }
    Cursor first(){
            return Cursor(&head_);
    }
    bool is_last(const Cursor& p)const{
            return p.p_ == &head_;
    }
    bool is_empty()const{
            return head_.next_ == &head_;
    }

private:
    Link head_;
};
#endif

    
    
    
    
            
            

    
